package com.flying.refdata.batchload.wind;

import com.flying.refdata.batchload.FileUploader;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.io.FileInputStream;
import java.util.List;

public class ExcelUploader implements FileUploader {
    private static Logger logger = LoggerFactory.getLogger(ExcelUploader.class);
    @Autowired
    private List<ExcelEquityProcessor> processors;

    @Autowired
    private ThreadPoolTaskExecutor executor;

    public void upload(String fileName) throws Exception {
        logger.info(">>>>Start to uploading file: " + fileName + "; Current Time is : " + System.currentTimeMillis());
        try (Workbook wb = WorkbookFactory.create(new FileInputStream(fileName))) {
            ExcelEquityProcessor processor;
            for (Sheet sheet : wb) {
                processor = lookupAvailableProcessor(sheet);
                if (processor == null) {
                    logger.info("No available processor for file:" + fileName + " and sheet: " + sheet.getSheetName());
                    continue;
                }
                for (Row row : sheet) {
                    dispatchToWorker(processor, sheet, row);
                }
            }
        } catch (Exception e) {
            logger.error("Exception occurs when handling:" + fileName, e);
        }
    }

    private void dispatchToWorker(ExcelEquityProcessor processor, Sheet sheet, Row row) {
        ImportWorker worker = new ImportWorker(processor, sheet, row);
        executor.execute(worker);
    }

    private ExcelEquityProcessor lookupAvailableProcessor(Sheet sheet) {
        for (ExcelEquityProcessor processor : processors) {
            if (processor.isValidSheet(sheet)) return processor;
        }
        return null;
    }
}